本文のサンプルソースでは値によって誤動作するので差し替えます。(257ページ)
Minで目的の値に最も近い値を選ぶ §
最大でも最小でもない値をMin/Maxメソッドで選ぶのは難しいように思える。しかし、一歩引いて考えるとそうでもない。「目的の値に最も近い値を選ぶ」という要求は、「目的の値との差の絶対値が最小の値を選ぶ」と読み替えればMinメソッドで処理可能だ。
using System;
using System.Linq;
class Program
{
static void Main()
{
const int target1 = 10;
const int target2 = 13;
int[] a = { 8, 11, 12 };
int min1 = a.Min(c => Math.Abs(c - target1));
Console.WriteLine("{0}にいちばん近い値は{1}です。", target1, a.First(c => Math.Abs(c - target1) == min1));
int min2 = a.Min(c => Math.Abs(c - target2));
Console.WriteLine("{0}にいちばん近い値は{1}です。", target2, a.First(c => Math.Abs(c - target2) == min2));
}
}
実行結果:
10にいちばん近い値は11です。
13にいちばん近い値は12です。
この場合、「差の最小値」をMinメソッドは求めるが、それは目的とする値との差である。しかし、この値からは符合に関する情報が失われているので、もう1回Firstメソッドでその値を持つ要素を検索して元の値を取得して出力している。
ちなみに、Math.Min/Math.MaxメソッドにはLINQに同じ名前のMin/Maxメソッドがあるが、Math.Absメソッドは対応するLINQのメソッドは無い。なぜならMath.Absメソッドの効能は1つの値の絶対値を得ることだけで、シーケンスとは何ら関係ないからだ。